# Author ： chosen-yn
import os
import subprocess
from datetime import datetime

from conf import LOG_DIR
from Config import *
from xtquant import xtconstant
from lib import get_logger, validate_stock_code, create_log, get_stock_account, validate_order_number
import pandas as pd


# 生成日志对象
def logger(stock_account, name=''):
    file_path = os.path.join(LOG_DIR, f'{stock_account}.log')
    return get_logger(file_path=file_path, name=name)


# 买单
def check_buy_order():
    stock_account = get_stock_account()
    print("请输入你需要买的股票号：")
    stock_number_buy = str(input())
    print("请输入你需要购买的数量")
    quantity_buy = int(input())
    print("请输入你购买的单价")
    price_buy = float(input())

    # 校验股票号
    flag, msg = validate_stock_code(stock_number_buy)
    if not flag:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg

    fix_result_order_id_buy = xt_trader.order_stock(account_putong, stock_number_buy, xtconstant.STOCK_BUY,
                                                    quantity_buy, xtconstant.FIX_PRICE, price_buy, 'strategy1',
                                                    '买入')
    return True, fix_result_order_id_buy


# 卖单
def sell_order():
    stock_account = get_stock_account()
    print("请输入你需要卖出的股票号：")
    stock_number_sell = str(input())
    print("请输入你需要卖出的数量")
    quantity_sell = int(input())
    print("请输入你卖出的单价")
    price_sell = float(input())

    # 校验股票号
    flag, msg = validate_stock_code(stock_number_sell)
    if not flag:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg

    fix_result_order_id_sell = xt_trader.order_stock(account_putong, stock_number_sell, xtconstant.STOCK_SELL,
                                                     quantity_sell, xtconstant.FIX_PRICE, price_sell, 'strategy1',
                                                     '卖出')
    return True, fix_result_order_id_sell


# 买单撤单
def buy_cancel_order():
    stock_account = get_stock_account()
    acc = StockAccount('10100001021')
    order_number = int(input(f"请输入你需要买单撤单的订单编号:").strip())
    flag, msg = validate_order_number(order_number)
    if not flag:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg
    xt_trader.cancel_order_stock(acc, order_number)
    return True, f'订单号{order_number}撤单成功! '


# 卖单撤单
def sell_cancel_order():
    stock_account = get_stock_account()
    acc = StockAccount('10100001021')
    order_number = int(input(f"请输入你需要卖单撤单的订单编号:").strip())
    flag, msg = validate_order_number(order_number)
    if not flag:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg
    xt_trader.cancel_order_stock(acc, order_number)
    return True, f'订单号{order_number}撤单成功! '


# 查看实时行情
def view_market_data():
    stock_account = get_stock_account()
    stock_number = str(input(f"请输入需要查看的股票号:").strip())
    flag, msg = validate_stock_code(stock_number)
    if flag:
        quote_dict = xtdata.get_full_tick(code_list=[stock_number])
        if quote_dict:
            df = pd.DataFrame(quote_dict)
            df = df.T
            df.reset_index(inplace=True)

            mapping = {'index': '证券代码', 'timetag': '时间', 'lastPrice': '最新价', 'open': '开盘价',
                       'high': '最高价',
                       'low': '最低价',
                       'lastClose': '昨收价', 'amount': '成交额', 'volume': '成交量', 'pvolume': '原始成交总量',
                       'settlementPrice': '今结算', 'lastSettlementPrice': '前结算', 'askPrice': '五档卖价',
                       'bidPrice': '五档买价',
                       'aslVol': '五档卖量', 'bidVol': '五档买量'
                       }
            df.rename(columns=mapping, inplace=True)
            df = df[
                ['证券代码', '时间', '最新价', '开盘价', '最高价', '最低价', '昨收价', '成交额', '成交量', '五档卖价',
                 '五档买价', '五档买量']]
            return True, df
        else:
            return False, f'未获取到实时行情数据'
    else:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg


# 下载历史行情
def download_history_data():
    stock_account = get_stock_account()
    stock_number = input("请输入要下载的股票代码:").strip()
    flag, msg = validate_stock_code(stock_number)
    if not flag:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg
    else:
        start_time = input("请输入开始日期 (YYYYMMDD):")
        end_time = input("请输入结束日期 (YYYYMMDD):")
        try:
            def on_progress(data):
                print(data)

            download_data = xtdata.download_history_data2(stock_list=[stock_number], period='tick',
                                                          start_time=start_time,
                                                          end_time=end_time, callback=on_progress)
            return True, f'{download_data}下载成功！'
        except Exception as e:
            return False, f'下载历史数据失败,失败原因:{e}'


# 查询账户信息
def query_account_info():
    return True, subprocess.run(["python", "获取账户信息.py"])


# 订阅并获取数据
def subscrib_obtain_data():
    stock_number = str(input(f"请输入你需要订阅的股票号:").strip())
    flag, msg = validate_stock_code(stock_number)

    if flag:
        def on_data(data):
            print(data)

        seq = xtdata.subscribe_whole_quote(code_list=[stock_number], callback=on_data)
        if seq:
            return True, f'订阅成功，订阅号为:{seq}'
        else:
            return False, f'订阅失败'
    else:
        return False, msg


# 取消订阅
def unsubscribe():
    stock_number = str(input(f"取消订阅的股票号:").strip())

    flag, msg = validate_stock_code(stock_number)
    if flag:
        def on_data(data):
            print(data)

        seq = xtdata.subscribe_whole_quote(code_list=[stock_number], callback=on_data)
        # 取消订阅
        xtdata.unsubscribe_quote(seq)
        return True, f'取消订阅号:{seq} 成功！'
    else:
        return False, msg


# 查看本地历史行情
def view_local_history_data():
    stock_account = get_stock_account()
    stock_number = str(input("请输入你需要查询的股票号:").strip())
    start_time = str(input("请输入需要查询的开始时间:").strip())
    end_time = str(input("请输入需要查询的结束时间:").strip())
    flag, msg = validate_stock_code(stock_number)
    if flag:
        df = xtdata.get_local_data(stock_list=[stock_number], period='1d', start_time=start_time, end_time=end_time)
        return True, df
    else:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg


# 三秒撤买单
def three_withdrawal_buy_order():
    stock_account = get_stock_account()
    acc = StockAccount('10100001021')
    stock_number_buy = str(input("请输入你需要购买的股票号:").strip())
    flag, msg = validate_stock_code(stock_number_buy)
    if flag:
        quantity_buy = int(input("请输入你需要购买的数量:").strip())
        price_buy = float(input("请输入你需要购买的单价:").strip())
        fix_result_order_id_buy = xt_trader.order_stock(account_putong, stock_number_buy, xtconstant.STOCK_BUY,
                                                        quantity_buy, xtconstant.FIX_PRICE, price_buy, 'strategy1',
                                                        '买入')
        print('正在进行三秒撤买单...')
        time.sleep(3)
        positions = xt_trader.query_stock_positions(account_putong)
        if positions:
            print("正在撤单中...")
            cancel_order_id = xt_trader.cancel_order_stock(acc, fix_result_order_id_buy)
            if cancel_order_id == 0:
                return True, f'撤单成功，撤单编号为:{cancel_order_id}'
            else:
                return False, f'撤单失败'
        else:
            return False, f'未获取到持仓信息'
    else:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg


# 三秒撤卖单
def three_withdrawal_sell_order():
    stock_account = get_stock_account()
    acc = StockAccount('10100001021')
    stock_number_sell = str(input("请输入需要卖出的股票号:").strip())
    flag, msg = validate_stock_code(stock_number_sell)
    if flag:
        quantity_sell = int(input("请输入需要卖出的数量:").strip())
        price_sell = float(input("请输入需要卖出的单价:").strip())
        fix_result_order_id_sell = xt_trader.order_stock(account_putong, stock_number_sell, xtconstant.STOCK_SELL,
                                                         quantity_sell, xtconstant.FIX_PRICE, price_sell, 'strategy1',
                                                         '卖出')
        print("正在进行三秒撤卖单....")
        time.sleep(3)
        positions = xt_trader.query_stock_positions(account_putong)
        if positions:
            print('正在撤单中...')
            cancel_order_id = xt_trader.cancel_order_stock(acc, fix_result_order_id_sell)
            if cancel_order_id == 0:
                return True, f'撤单成功，撤单编号为:{cancel_order_id}'
            else:
                return False, f'撤单失败'
        else:
            return False, f'未获取到持仓信息'
    else:
        log = create_log(log=msg, acc=stock_account)
        logger(stock_account, name='func').warning(log)
        return False, msg
